﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;

namespace JXT.PrimaryKey.Batman.Reflection
{
    /// <summary>
    /// 模型对象帮助类
    /// </summary>
    public static class MetadataExtensions
    {
        private static readonly ConcurrentDictionary<Type, Dictionary<string,LambdaReflectionMetadate>> cache
            = new ConcurrentDictionary<Type, Dictionary<string, LambdaReflectionMetadate>>();

        /// <summary>
        /// 获取指定类型的模型元数据字典
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <returns></returns>
        public static Dictionary<string, LambdaReflectionMetadate> GetMetadataCacheDictionary(this Type type)
        {
            Dictionary<string, LambdaReflectionMetadate> find;
            if (!cache.TryGetValue(type, out find))
            {
                find = createCacheDictionary(type);
                cache.AddOrUpdate(type, find, (e1, e2) => e2);
            }
            return find;
        }

        /// <summary>
        /// 获取指定类型指定名称的元数据缓存对象
        /// </summary>
        /// <param name="type">模型类型</param>
        /// <param name="name">属性名称</param>
        /// <returns></returns>
        public static LambdaReflectionMetadate GetMetadataCacheItem(this Type type, string name)
        {
            var dic = GetMetadataCacheDictionary(type);
            LambdaReflectionMetadate find;
            if (!dic.TryGetValue(name, out find))
            {
                find = null;
            }
            return find;
        }

        /// <summary>
        /// 获取指定类型的元数据缓存对象数组
        /// </summary>
        /// <typeparam name="T">模型类型</typeparam>
        /// <returns></returns>
        public static LambdaReflectionMetadate[] GetMetadataCacheItems<T>(this T instanse)
        {
            return GetMetadataCacheDictionary(typeof(T)).Select(e => e.Value).ToArray();
        }

        /// <summary>
        /// 获取指定类型的元数据缓存对象数组
        /// </summary>
        /// <typeparam name="T">模型类型</typeparam>
        /// <returns></returns>
        public static LambdaReflectionMetadate[] GetMetadataCacheItems(this Type type)
        {
            return GetMetadataCacheDictionary(type).Select(e => e.Value).ToArray();
        }

        /// <summary>
        /// 获取指定类型指定名称的元数据缓存对象
        /// </summary>
        /// <typeparam name="T">模型类型</typeparam>
        /// <param name="name">模型名称</param>
        /// <returns></returns>
        public static LambdaReflectionMetadate GetMetadataCacheItem<T>(this T isntanse, string name)
        {
            return GetMetadataCacheItem(typeof(T), name);
        }

        /// <summary>
        /// 创建指定类型的元数据字典
        /// </summary>
        /// <param name="type">类型名</param>
        /// <returns></returns>
        private static Dictionary<string, LambdaReflectionMetadate> createCacheDictionary(this Type type)
        {
            Dictionary<string, LambdaReflectionMetadate> result = new Dictionary<string, LambdaReflectionMetadate>();
            var properties = type.GetProperties();
            foreach (var item in properties)
            {
                result.Add(item.Name, new LambdaReflectionMetadate(item));
            }
            return result;
        }
    }
}
